package cn.lingyangwl.agile.msg.push.core.channel.client;

import cn.lingyangwl.agile.msg.push.core.channel.MsgChannel;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.Setter;
import org.springframework.boot.autoconfigure.mail.MailProperties;
import org.springframework.mail.javamail.JavaMailSenderImpl;

import java.util.Map;
import java.util.Properties;

/**
 * 邮箱客户端
 * @author shenguangyang
 */
@Getter
@Setter
@EqualsAndHashCode(callSuper = true)
public abstract class AbstractEmailMsgClient extends BaseMsgChannelClient {

    protected JavaMailSenderImpl javaMailSender;
    protected MailProperties mailProperties;

    public AbstractEmailMsgClient(MsgChannel channel) {
        super(channel);
    }

    protected void initMailSender() {
        this.javaMailSender = new JavaMailSenderImpl();
        // 腾讯云和阿里云对25端口限制了, 需要使用465端口, 465端口是为SMTPS（SMTP-over-SSL）协议服务开放的
        this.mailProperties.setPort(465);
        applyProperties(this.mailProperties, this.javaMailSender);
    }

    private void applyProperties(MailProperties properties, JavaMailSenderImpl sender) {
        sender.setHost(properties.getHost());
        if (properties.getPort() != null) {
            sender.setPort(properties.getPort());
        }
        sender.setUsername(properties.getUsername());
        sender.setPassword(properties.getPassword());
        sender.setProtocol(properties.getProtocol());
        if (properties.getDefaultEncoding() != null) {
            sender.setDefaultEncoding(properties.getDefaultEncoding().name());
        }
        if (!properties.getProperties().isEmpty()) {
            sender.setJavaMailProperties(asProperties(properties.getProperties()));
        }

        // 如果使用465端口, 需要设置 socketFactory 为 SSLSocketFactory
        sender.getJavaMailProperties().put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
        sender.getJavaMailProperties().put("mail.smtp.auth", true);
    }

    private Properties asProperties(Map<String, String> source) {
        Properties properties = new Properties();
        properties.putAll(source);
        return properties;
    }
}
